package com.hmkj.core.service.operate.impl;

import com.alibaba.fastjson.JSON;
import com.hmkj.common.baseMapper.GenericMapper;
import com.hmkj.common.baseMapper.GenericPo;
import com.hmkj.core.constant.CacheID;
import com.hmkj.core.constant.ConfigNID;
import com.hmkj.core.constant.PointNid;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.mapper.amount.PointLogMapper;
import com.hmkj.core.mapper.amount.RechargeMapper;
import com.hmkj.core.mapper.operate.PointRuleMapper;
import com.hmkj.core.mapper.order.OrderMapper;
import com.hmkj.core.mapper.order.OrderSimulateMapper;
import com.hmkj.core.mapper.user.UserMapper;
import com.hmkj.core.po.amount.Recharge;
import com.hmkj.core.po.operate.PointRule;
import com.hmkj.core.po.order.Order;
import com.hmkj.core.po.order.OrderSimulate;
import com.hmkj.core.po.user.PointLog;
import com.hmkj.core.po.user.User;
import com.hmkj.core.service.cache.RedisService;
import com.hmkj.core.service.operate.PointRuleService;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户积分奖励规则表业务相关Service接口实现<br>
 *
 * @author eproo
 * @ClassName: PointRuleServiceImpl
 * @date 2017-11-24 03:03:26
 */
@Slf4j
@Service
@Scope("prototype")
@Transactional(rollbackFor = Exception.class)
public class PointRuleServiceImpl implements PointRuleService {

    @Resource
    private PointRuleMapper pointRuleMapper;
    @Resource
    private PointLogMapper pointLogMapper;
    @Resource
    private RechargeMapper rechargeMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisService redisService;
    @Resource
    private OrderSimulateMapper orderSimulateMapper;
    @Resource
    private OrderMapper orderMapper;

    @Override
    public GenericMapper<PointRule, Integer> _getMapper() {
        return pointRuleMapper;
    }

    @Override
    public void doEdit(PointRule model) throws Exception {
        PointRule pointRule = pointRuleMapper.selectOne(new PointRule(u -> {
            u.setId(model.getId());
            u.setDelFlag(PointRule.DELFLAG.NORMAL.code);
        }));
        if (null == pointRule) {
            throw new BussinessException("该积分规则不存在");
        }
        pointRuleMapper.updateByPrimaryKeySelective(new PointRule(u -> {
            u.setId(model.getId());
            u.setTitle(model.getTitle());
            u.setValue(model.getValue());
            u.setRemark(model.getRemark());
            u.setDelFlag(PointRule.DELFLAG.NORMAL.code);
        }));
    }
    @Override
    public void sendPoint(Integer userId, PointNid nid) {
        Map<String, Object> data = new HashMap<>();
        data.put("userId", userId);
        data.put("nid", nid.nid);
        log.info("加入积分发放队列：{}", JSON.toJSONString(data));
        redisService.push(CacheID.QUEUE_POINT, data);
    }

    @Override
    public void doSendPoint(Integer userId, PointNid nid) {
        PointRule rule = pointRuleMapper.selectOne(new PointRule(t -> {
            t.setNid(nid.nid);
            t.setStatus(PointRule.STATUS.T1.code);
            t.setDelFlag(GenericPo.DELFLAG.NORMAL.code);
        }));
        // 没有规则或规则未启用
        if (rule == null) return;

        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null) return;

        // 计算奖励数量
        int amount = 0;
        if (PointNid.T3.equals(nid)) {
            // 判断是否是首次充值
            List<Recharge> list = rechargeMapper.select(new Recharge(t -> {
                t.setUserId(userId);
                t.setStatus(Recharge.STATUS.T3.code);
                t.setDelFlag(GenericPo.DELFLAG.NORMAL.code);
            }));
            if (list.size() > 1) return;
            amount = Integer.parseInt(rule.getValue());
        } else if (PointNid.T4.equals(nid)) {
            // 查询累计充值成功的金额
            BigDecimal rechargeMoney = rechargeMapper.findRechargeAllMoney(userId);
            //查询已送积分记录
            List<PointLog> userRechargePointLogs = pointLogMapper.select(new PointLog(t->{
                t.setUserId(userId);
                t.setNid(PointNid.T4.nid);
                t.setDelFlag(PointLog.DELFLAG.NORMAL.code);
            }));
            int alreadyGetPointCount = 0;
            if(null != userRechargePointLogs){
                alreadyGetPointCount= userRechargePointLogs.size();
            }
            String[] args = rule.getValue().split(";");
            if(alreadyGetPointCount<args.length){
                int point = 0;
                int ruleStart = 0;
                for (String arg : args) {
                    ruleStart++;
                    if(ruleStart>alreadyGetPointCount){
                        if (StrUtil.isNotBlank(arg)) {
                            String[] items = arg.split(",");
                            BigDecimal limit = new BigDecimal(items[0]);
                            point += Integer.parseInt(items[1]);
                            if (rechargeMoney.compareTo(limit) >= 0) {
                                amount = point;
                            }
                        }
                    }
                }
            }
        } else if (PointNid.T5.equals(nid)) {
            // 查询模拟交易奖励次数
            int count = redisService.get(ConfigNID.REWARD_COUNT_SIMU, Integer.class);
            List<OrderSimulate> list = orderSimulateMapper.selectSucByUID(userId);
            if(null == list || list.size() == 0 || list.size() > count)return;
            //查询模拟交易送积分的记录
            List<PointLog> pointLogs = pointLogMapper.select(new PointLog(t->{
                t.setUserId(userId);
                t.setNid(PointNid.T5.nid);
                t.setDelFlag(PointLog.DELFLAG.NORMAL.code);
            }));
            if(pointLogs.size()>= count)return;
            amount = Integer.parseInt(rule.getValue());
        } else if (PointNid.T6.equals(nid)) {
            // 查询实盘交易奖励次数
            int count = redisService.get(ConfigNID.REWARD_COUNT, Integer.class);
            List<Order> list = orderMapper.selectSucByUID(userId);
            if (null == list || list.size() == 0 || list.size() > count) return;
            //查询实盘交易送积分的记录
            List<PointLog> pointLogs = pointLogMapper.select(new PointLog(t->{
                t.setUserId(userId);
                t.setNid(PointNid.T6.nid);
                t.setDelFlag(PointLog.DELFLAG.NORMAL.code);
            }));
            if(pointLogs.size()>= count)return;
            amount = Integer.parseInt(rule.getValue());
        }else {
            amount = Integer.parseInt(rule.getValue());
        }

        if (amount > 0) {
            if (pointLogMapper.insert(PointLog.buildLog(user, amount, nid, rule.getTitle())) != 1) {
                throw new BussinessException("保存积分记录是失败");
            }
            if (userMapper.updatePoint(amount, userId) != 1) {
                throw new BussinessException("发送积分是失败");
            }
        }

    }
}
